/*
 * Matt Adams
 * TCSS 558 HW2
 * Fall 2013
 */
package rmi;

import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Iterator;
import java.util.SortedSet;

import tools.Log;
import tools.WordList;

/**
 * @author Matt Adams
 */
public class RemoteSpellingObject implements RemoteSpelling {
    
    /**
     * List containing database of words.
     */
    private final WordList wordList;
    
    /**
     * Constructs RemoteSpellingObject object.
     * 
     * @param filename Filename of a word list.
     * @throws IOException IO Exception.
     */
    public RemoteSpellingObject(final String filename) throws IOException {
        
        this.wordList = new WordList(filename);
    }
    
    /**
     * Check the spelling of the specified word.
     * 
     * @param the_word The word to check.
     * @return a sorted set of suggestions (which may be empty) if the word is
     *         spelled incorrectly, or null if the word is spelled correctly.
     * @throws RemoteException if there is a problem completing the method call.
     */
    @Override
    public SortedSet<String> check(final String word) throws RemoteException {
        Log.out("Received query for word: " + word);
        SortedSet<String> result = null;
        if (!this.wordList.isInList(word)) {
            result = this.wordList.getCloseWords(word);
            displayQueryResponse(word, result.size(), result);
        } else {
            //word spelled correctly
            displayQueryResponse(word, -1, result);
        }
        return result;
    }

    /**
     * Add the specified word to the word list. If the word is already in the
     * word list, this method has no effect.
     * 
     * @param the_word The word to add.
     * @throws RemoteException if there is a problem completing the method call.
     */
    @Override
    public void add(final String word) throws RemoteException {
        if (!this.wordList.isInList(word)) {
            this.wordList.add(word);
            Log.out("Word list updated. Added word: " + word);
        } else {
            Log.out("Word list unchanged (Add attempt). Following word is already in the list: " + word);
        }

    }

    /**
     * Remove the specified word from the word list. If the word is not in the
     * word list, this method has no effect.
     * 
     * @param the_word The word to remove.
     * @throws RemoteException if there is a problem completing the method call.
     */
    @Override
    public void remove(final String word) throws RemoteException {
        if (this.wordList.isInList(word)) {
            this.wordList.remove(word);
            Log.out("Word list updated. Removed word: " + word);
        } else {
            Log.out("Word list unchanged (Remove attempt). Following word was not found in the list: " + word);
        }
    }
    
    /**
     * Properly displays response to query.
     * 
     * @param queriedWord Queried word.
     * @param numberOfWords Number of close words.
     * @param closeWords Set of close words.
     * @return Returns formatted string of close words.
     */
    private String displayQueryResponse(final String queriedWord, final int numberOfWords, final SortedSet<String> closeWords) {
        String closeWordString = null;
        if (numberOfWords < 0) {
            Log.out(queriedWord + " is spelled correctly.");
        } else if (numberOfWords == 0) {
            Log.out(queriedWord + " is spelled incorrectly. There are no suggestions.");
        } else {     
            final StringBuilder sb = new StringBuilder();
            final Iterator<String> itr = closeWords.iterator();
            int count = 1;
            while (itr.hasNext() && count <= numberOfWords) {
                final String closeWord = itr.next();
                sb.append(closeWord);
                sb.append(" ");
                count++;
            }
            closeWordString = sb.toString();
            Log.out(queriedWord + " is spelled incorrectly.");
            Log.out("There are " + numberOfWords + " suggested words: " + closeWordString);
        }
        return closeWordString;
    }

}
